#pragma once
#include <cstdint>
#include "./utils/random_pair_list.hpp"


namespace clay {
    template<std::uint16_t mapper_size>
    std::array<std::uint8_t, mapper_size> generateRandomNoReflexiveMapping(const std::uint64_t seed)
    {
        std::uint8_t from, to;
        std::array<std::uint8_t, mapper_size> mapping;
        std::vector<mapping_pair_type> pair_list = generateRandomNoReflexiveMappingPairList<mapper_size>(seed);

        for (const mapping_pair_type& pair : pair_list) {
            from = pair.first;
            to = pair.second;

            mapping[from] = to;
            mapping[to] = from;
        }

        return mapping;
    }


    template<std::uint16_t charset_size>
    class Reflector final {
    private:
        std::array<std::uint8_t, charset_size> mapping;
    public:
        Reflector(const std::uint64_t seed = 0x123456)
            : mapping(generateRandomNoReflexiveMapping<charset_size>(seed))
        {}


        std::uint8_t Map(const std::uint8_t value) const
        {
            return mapping.at(value);
        }
    };

}